class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        int n = matrix.size();
        vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX));
        for (int j = 0; j <= n + 1; j++) dp[0][j] = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                dp[i][j] = min(min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + matrix[i - 1][j - 1];
        int ret = INT_MAX;
        for (int i = 1; i <= n; i++)
            ret = min(ret, dp[n][i]);
        return ret;
    }
};
class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
        dp[0][1] = dp[1][0] = 0;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
        return dp[m][n];

    }
};
class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& d) {
        int m = d.size(), n = d[0].size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
        dp[m][n - 1] = dp[m - 1][n] = 1;
        for (int i = m - 1; i >= 0; i--)
            for (int j = n - 1; j >= 0; j--)
            {
                dp[i][j] = min(dp[i][j + 1], dp[i + 1][j]) - d[i][j];
                dp[i][j] = max(1, dp[i][j]);
            }
        return dp[0][0];
    }
};
class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        int n = nums.size();
        if (n == 1) return to_string(nums[0]);
        if (n == 2) return to_string(nums[0]) + "/" + to_string(nums[1]);
        string ret = to_string(nums[0]) + "/(" + to_string(nums[1]);
        for (int i = 2; i < n; i++)
        {
            ret += "/" + to_string(nums[i]);
        }
        ret += ")";
        return ret;
    }
};
class Solution {
public:
    int jump(vector<int>& nums) {
        int left = 0, right = 0, maxpos = 0, ret = 0, n = nums.size();
        while (left <= right)
        {
            if (maxpos >= n - 1)
            {
                return ret;
            }
            for (int i = left; i <= right; i++)
            {
                maxpos = max(maxpos, nums[i] + i);
            }
            left = right + 1;
            right = maxpos;
            ret++;
        }
        return -1;

    }
};
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int left = 0, right = 0, maxpos = 0, n = nums.size();
        while (left <= right)
        {
            if (maxpos >= n - 1)
            {
                return true;
            }
            for (int i = left; i <= right; i++)
            {
                maxpos = max(maxpos, nums[i] + i);
            }
            left = right + 1;
            right = maxpos;
        }
        return false;

    }
};
class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int n = gas.size();
        for (int i = 0; i < n; i++)
        {
            int ret = 0;
            int step = 0;
            for (; step < n; step++)
            {
                int index = (i + step) % n;
                ret += gas[index] - cost[index];
                if (ret < 0) break;
            }
            if (ret >= 0) return i;
            i += step;
        }
        return -1;

    }
};